package com.cskaoyan.wordmemorize.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cskaoyan.wordmemorize.common.aspect.operate.OperateLog;
import com.cskaoyan.wordmemorize.common.aspect.operate.OperateLogConstant;
import com.cskaoyan.wordmemorize.common.constant.ResultCodeEnum;
import com.cskaoyan.wordmemorize.common.exception.BusinessException;
import com.cskaoyan.wordmemorize.converter.VocBookConverter;
import com.cskaoyan.wordmemorize.dao.entity.OperateLogDO;
import com.cskaoyan.wordmemorize.dao.entity.VocBookDO;
import com.cskaoyan.wordmemorize.dao.entity.VocChapBookDO;
import com.cskaoyan.wordmemorize.dao.entity.VocChapterDO;
import com.cskaoyan.wordmemorize.dao.mapper.VocBookMapper;
import com.cskaoyan.wordmemorize.dao.mapper.VocChapBookMapper;
import com.cskaoyan.wordmemorize.dao.mapper.VocChapterMapper;
import com.cskaoyan.wordmemorize.dto.admin.DeleteBookOperateDTO;
import com.cskaoyan.wordmemorize.dto.admin.PageDTO;
import com.cskaoyan.wordmemorize.dto.admin.VocBookDTO;
import com.cskaoyan.wordmemorize.request.BatchDeleteCommand;
import com.cskaoyan.wordmemorize.request.VocBookCommand;
import com.cskaoyan.wordmemorize.request.VocBookPageRequest;
import com.cskaoyan.wordmemorize.service.VocBookService;
import org.jetbrains.annotations.NotNull;
import org.mapstruct.ap.shaded.freemarker.template.utility.StringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class VocBookServiceImpl extends ServiceImpl<VocBookMapper, VocBookDO> implements VocBookService {

    @Autowired
    private VocBookConverter vocBookConverter;

    @Autowired
    private VocBookMapper vocBookMapper;

    @Autowired
    private VocChapterMapper vocChapterMapper;

    @Autowired
    private VocChapBookMapper vocChapBookMapper;

    @Override
    public PageDTO<VocBookDTO> getBookPage(VocBookPageRequest pageQuery) {
        System.out.println("以下是获取书籍列表");

        if (pageQuery.getPageNum() == null){
            System.out.println("书籍页面" + pageQuery.getPageNum());
            LambdaQueryWrapper<VocBookDO> vocBookQueryWrapper = new LambdaQueryWrapper<>();
            vocBookQueryWrapper.eq(VocBookDO::getBcId, pageQuery.getCategoryId());

            List<VocBookDO> vocBookDOS = vocBookMapper.selectList(vocBookQueryWrapper);

            return vocBookConverter.vocBookList2Page(vocBookDOS, (long) vocBookDOS.size());
        }

        // 分页查询
        Page<VocBookDO> pageParam = new Page<>(pageQuery.getPageNum(), pageQuery.getCount());
        LambdaQueryWrapper<VocBookDO> vocBookQueryWrapper = new LambdaQueryWrapper<>();
        //模糊匹配
        if (StringUtil.emptyToNull(pageQuery.getKeyword()) != null) {
            vocBookQueryWrapper.like(VocBookDO::getName, pageQuery.getKeyword());
        }
        //获取该类目下的书籍
        vocBookQueryWrapper.eq(VocBookDO::getBcId, pageQuery.getCategoryId());
        Page<VocBookDO> vocBookDOPagePage = vocBookMapper.selectPage(pageParam, vocBookQueryWrapper);

        List<VocBookDO> records = getChapterCountAndVocCount(vocBookDOPagePage);

        return vocBookConverter.vocBookList2Page(records, vocBookDOPagePage.getTotal());
    }

    /**
     * 获取该书籍下的章节数量和单词数量
     * @param vocBookDOPagePage
     * @return
     */
    @NotNull
    private List<VocBookDO> getChapterCountAndVocCount(Page<VocBookDO> vocBookDOPagePage) {
        List<VocBookDO> records = vocBookDOPagePage.getRecords();

        records.forEach(vocBookDO -> {
            //获取该书籍下的章节数量
            LambdaQueryWrapper<VocChapterDO> vocChapterDOQueryWrapper = new LambdaQueryWrapper<>();
            vocChapterDOQueryWrapper.eq(VocChapterDO::getBookId, vocBookDO.getId());
            Long chapterCount = vocChapterMapper.selectCount(vocChapterDOQueryWrapper);
            System.out.println("章节数量 = " + chapterCount);
            vocBookDO.setChapterCount(Integer.valueOf(chapterCount + ""));

            //获取该书籍下的单词数量
            LambdaQueryWrapper<VocChapBookDO> vocChapBookDOQueryWrapper = new LambdaQueryWrapper<>();
            vocChapBookDOQueryWrapper.eq(VocChapBookDO::getBookId, vocBookDO.getId());
            Long wordCount = vocChapBookMapper.selectCount(vocChapBookDOQueryWrapper);
            System.out.println("单词数量 = " + wordCount);
            vocBookDO.setVocCount(Integer.valueOf(wordCount + ""));
        });
        return records;
    }


    @OperateLog(dateType = "书籍", operateType = OperateLogConstant.OPERATE_ADD)
    @Override
    public Long addVocBook(VocBookCommand command) {
        System.out.println("以下是添加书籍");
        VocBookDO vocBookDO = vocBookConverter.vocBookCommand2VocBookDO(command);
        int insert = vocBookMapper.insert(vocBookDO);
        if (insert == 0){
            throw new BusinessException(ResultCodeEnum.FAIL);
        }
        return null;
    }

    @OperateLog(dateType = "书籍", operateType = OperateLogConstant.OPERATE_UPDATE)
    @Override
    public void updateVocBook(VocBookCommand command) {
        System.out.println("以下是修改书籍");
        VocBookDO vocBookDO = vocBookConverter.vocBookCommand2VocBookDO(command);
        vocBookDO.setId(Long.valueOf(command.getId()));
        int update = vocBookMapper.updateById(vocBookDO);
        if (update == 0){
            throw new BusinessException(ResultCodeEnum.FAIL);
        }

    }

    @Transactional
    @OperateLog(dateType = "书籍", operateType = OperateLogConstant.OPERATE_SINGLE_DELETE)
    @Override
    public DeleteBookOperateDTO deleteVocBook(Long bookId) {
        System.out.println("以下是删除指定的书籍");
        VocBookDO vocBookDO = vocBookMapper.selectById(bookId);
        int row1 = vocBookMapper.deleteById(bookId);

        Map<String, Object> map = new HashMap<>();
        map.put("book_id",bookId);
        int row2 = vocChapterMapper.deleteByMap(map);
        int row3 = vocChapBookMapper.deleteByMap(map);

        if (row1 <= 0 || row2 < 0 || row3 < 0){
            throw new BusinessException(ResultCodeEnum.FAIL);
        }

        return vocBookConverter.vocBookDO2DeleteBookDTO(vocBookDO);
    }

    @Transactional
    @OperateLog(dateType = "书籍", operateType = OperateLogConstant.OPERATE_BATCH_DELETE)
    @Override
    public List<DeleteBookOperateDTO> deleteVocBooks(BatchDeleteCommand command) {
        System.out.println("以下是批量删除书籍");
        List<VocBookDO> vocBookDOS = vocBookMapper.selectByIds(command.getIds());
        int row1 = vocBookMapper.deleteByIds(command.getIds());
        //连表删除，删除voc_chapter表中的相关书籍
        LambdaQueryWrapper<VocChapterDO> chapterDOQueryWrapper = new LambdaQueryWrapper<>();
        chapterDOQueryWrapper.in(VocChapterDO::getBookId, command.getIds());
        int row2 = vocChapterMapper.delete(chapterDOQueryWrapper);
        //连表删除，删除voc_chap_book表中的相关书籍
        LambdaQueryWrapper<VocChapBookDO> vocChapBookDOQueryWrapper = new LambdaQueryWrapper<>();
        vocChapBookDOQueryWrapper.in(VocChapBookDO::getBookId, command.getIds());
        int row3 = vocChapterMapper.delete(chapterDOQueryWrapper);

        if (row1 <= 0 || row2 < 0 || row3 < 0){
            throw new BusinessException(ResultCodeEnum.FAIL);
        }

        return vocBookConverter.vocBookDOs2DeleteBookDTOs(vocBookDOS);
    }
}
